<?php

namespace App\Http\Controllers;

use App\Http\Requests\{MessageRequest, EmailScheduleRequest};
use App\Models\{Message, EmailSchedule, ScheduleItem, ScheduleBatch, QueueControl, DeliveryLog, Sender, DataExcel, Category, SubCategory, Tempelete};
use App\Jobs\{SendMultiMailsJob, PlanEmailScheduleJob, TestEmailJob};
use App\Traits\imagesTrait;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\{Mail, DB, Log};
use HTMLPurifier;
use HTMLPurifier_Config;
use Carbon\Carbon;
use SebastianBergmann\Template\Template;

class MessageController extends Controller
{
    use imagesTrait;

    public function index(Request $request)
    {
        // إحصائيات الرسائل الفورية
        $messageStats = Message::selectRaw('
        COUNT(*) as total,
        SUM(CASE WHEN status = "completed" THEN 1 ELSE 0 END) as completed,
        SUM(CASE WHEN status = "planning" THEN 1 ELSE 0 END) as planning,
        SUM(CASE WHEN status = "failed" THEN 1 ELSE 0 END) as failed
    ')->first();

        // إحصائيات الرسائل المجدولة
        $scheduleStats = [
            'total_schedules'   => EmailSchedule::count(),
            'running_schedules' => EmailSchedule::where('status', 'running')->count(),
            'paused_schedules'  => EmailSchedule::where('status', 'paused')->count(),
            'canceled_schedules' => EmailSchedule::where('status', 'canceled')->count(),
        ];

        // إحصائيات DeliveryLog
        $deliveryStats = [
            'queued' => DeliveryLog::where('status', 'queued')->count(),
            'sent'   => DeliveryLog::where('status', 'sent')->count(),
            'failed' => DeliveryLog::where('status', 'failed')->count(),
        ];
        // إجمالي سجلات التسليم (لـ عرض النسبة إن احتجنا)
        $deliveryStats['total'] = ($deliveryStats['queued'] ?? 0) + ($deliveryStats['sent'] ?? 0) + ($deliveryStats['failed'] ?? 0);

        // حساب آخر فشل عام (حتى يعرض في الـ view بدون خطأ)
        $lastFailure = DeliveryLog::where('status', 'failed')
            ->orderByDesc('logged_at')
            ->first();

        // الرسائل الفورية مع البحث
        $query = Message::query()->with(['sender', 'reciever']);

        if ($request->filled('search')) {
            $search = $request->search;
            $query->where(function ($q) use ($search) {
                $q->where('subject', 'like', "%{$search}%")
                    ->orWhereHas('sender', function ($q) use ($search) {
                        $q->where('name', 'like', "%{$search}%")
                            ->orWhere('email', 'like', "%{$search}%");
                    })
                    ->orWhereHas('reciever', function ($q) use ($search) {
                        $q->where('email', 'like', "%{$search}%");
                    })
                    ->orWhere('status', 'like', "%{$search}%");
            });
        }

        $messages = $query->orderBy('send_at', 'desc')
            ->paginate(10)
            ->appends(['search' => $request->search]);

        // الجداول المجدولة (عرض مبسّط في الصفحة الرئيسية)
        $scheduleQuery = EmailSchedule::with(['batches' => fn($q) => $q->orderBy('run_at'), 'message']);
        if ($request->filled('schedule_search')) {
            $scheduleQuery->where('label', 'like', '%' . $request->schedule_search . '%');
        }
        $schedules = $scheduleQuery->latest()
            ->paginate(10, ['*'], 'schedule_page')
            ->appends(['schedule_search' => $request->schedule_search]);

        // معلومات الـ Queues
        $queues = QueueControl::orderBy('queue_name')->get();

        // إحصاء الطوابير النشطة (مستخدم في العرض)
        $queueStats = [
            'active' => QueueControl::where('state', 'running')->count(),
        ];

        // عدد المستقبلين + تفاصيلهم (من DeliveryLog) لكل رسالة ظاهرة في الصفحة
        $messageToReceiverCount = [];
        $messageDetails = [];

        foreach ($messages as $msg) {
            // عدد المستقبلين (pivot table)
            $messageToReceiverCount[$msg->id] = DB::table('reciever_message')
                ->where('message_id', $msg->id)
                ->count();

            // تفاصيل من DeliveryLog (إيميل + حالة + وقت + خطأ)
            // ملاحظة: نستخدم حقول delivery log الأرجح: receiver_email, status, logged_at, error
            $logs = DeliveryLog::where('message_id', $msg->id)->orderBy('logged_at', 'desc')->get();

            $messageDetails[$msg->id] = $logs->map(fn($log) => [
                'email'   => $log->receiver_email,
                'status'  => $log->status,
                'sent_at' => $log->logged_at,
                'error'   => $log->error, // تأكد أن عمود خطأ في قاعدة البيانات اسمه 'error'
            ])->toArray();
        }

        return view('dashboard.Messages.index', compact(
            'messages',
            'schedules',
            'queues',
            'messageStats',
            'scheduleStats',
            'deliveryStats',
            'messageToReceiverCount',
            'messageDetails',
            'queueStats',
            'lastFailure'
        ));
    }

    public function create(Request $request)
    {
        $ids = $request->has('send_email_ids') ? explode(",", $request->send_email_ids) : [];
        $data['Datas'] = !empty($ids) ? DataExcel::whereIn('id', $ids)->get() : collect([]);
        $data['selected_category_ids'] = $data['Datas']->pluck('category_id')->unique()->filter()->toArray();

        $data['tempeletes'] = Tempelete::get();        
        $data['messages'] = Message::all();
        // $data['messages'] = Message::whereNotIn('status', ['running', 'complete'])->get();
        $data['categories'] = Category::all();
        $data['subcategories'] = SubCategory::all();
        $data['senders'] = Sender::all();
        $data['recievers'] = !empty($ids) ? $data['Datas'] : DataExcel::all();
        return view('dashboard.Messages.create', $data );
    }

    public function store(Request $request)
    {
        // تنظيف المحتوى
       $dirty_html = $request->input('content');
    $config = HTMLPurifier_Config::createDefault();
    $config->set('Cache.SerializerPath', storage_path('framework/cache/htmlpurifier'));
    $purifier = new HTMLPurifier($config);
    $clean_html = $purifier->purify($dirty_html);

        // رفع الملف المرفق
        $pathfile = null;
        if ($request->hasFile('file')) {
            $pathfile = $this->uploadImageimage($request->file('file'), 'attachemnts');
        }

        $senders = Sender::whereIn('id', $request->sender_id)->get();
        $receivers = DataExcel::whereIn('id', $request->data_excel_id)
            ->whereNotNull('email')->where('email', '<>', '')
            ->get();

        if ($senders->isEmpty() || $receivers->isEmpty()) {
            return redirect()->back()->with('error', 'No valid senders or receivers found')->withInput();
        }

        // ======= Important: start supervisor once (if you want Laravel to try to start workers) =======
        // (We keep your existing approach but call exec only once per request, not inside loops)
        try {
            exec('sudo supervisorctl start laravel-worker:* > /dev/null 2>&1 &');
        } catch (\Throwable $e) {
            // log but continue — starting supervisor is optional if it's already running
            Log::warning('Could not start supervisor from controller: ' . $e->getMessage());
        }

        if ($request->mode === 'now') {
            $message = Message::create([
                'subject' => $request->subject,
                'content' => $clean_html,
                'send_at' => now(),
                'file' => $pathfile,
                'status' => 'running',
                'send_mode' => 'now'
            ]);
            


    
            $senderIndex = 0;
            $usedSenders = [];


            foreach ($receivers as $receiver) {
                $sender = $senders[$senderIndex];

                if ($sender->get_messages_in_hour() < 400 && $sender->get_messages_in_day() < 2000)  {
                    // exec('sudo supervisorctl start laravel-worker:*');
                    SendMultiMailsJob::dispatch(
                        $sender->name,
                        $sender->email,
                        $receiver->email,
                        $clean_html,
                        $request->subject,
                        $message
                    );

                    $usedSenders[$sender->id] = $sender->id;
                }
                $senderIndex = ($senderIndex + 1) % $senders->count();
            }

            if (!empty($usedSenders)) {
                $message->sender()->attach(array_values($usedSenders));
            }
            $message->reciever()->attach($receivers->pluck('id')->toArray());
            return redirect()->route('message.index')->with('success', 'The message is saved and emails are being sent');
        } else {
            // return $request ;
            $message = Message::create([
                'subject' => $request->subject,
                'content' => $clean_html,
                'file' => $pathfile,
                'status' => 'planning',
                'send_mode' => 'schedule',
            ]);

            $message->sender()->attach($request->sender_id);
            $message->reciever()->attach($receivers->pluck('id')->toArray());

            $duration = $this->calculateOptimalDuration($senders->count(), $receivers->count());

            $schedule = EmailSchedule::create([
                'message_id' => $message->id,
                'sender_ids' => $request->sender_id,
                'receiver_ids' => $request->data_excel_id,
                'total_receivers' => $receivers->count(),
                'total_senders' => $senders->count(),
                'start_at' => $request->start_at,
                'duration_value' => $request->duration_value ?? $duration['value'],
                'duration_unit' => $request->duration_unit ?? $duration['unit'],
                'label' => $request->label ?? "Schedule for: {$request->subject}",
                'daily_cap_per_sender' => 2000,
                'hourly_cap_per_sender' => 400,
                'status' => 'planning',
            ]);

            // exec('sudo supervisorctl start laravel-worker:*');
            // PlanEmailScheduleJob::dispatch($schedule->id);
            // sleep(1);

            // TestEmailJob::dispatch($schedule->id);

            $startAt = Carbon::parse($schedule->start_at)->timezone('Africa/Cairo');
            $now = now('Africa/Cairo');

            $delayInSeconds = $now->diffInSeconds($startAt, false);

            if ($delayInSeconds < 0) {
                Log::warning("⚠️ Start time already passed. Running immediately.");
                $delayInSeconds = 0;
            }

            Log::info("🎯 StartAt: {$startAt} | Now: {$now} | DelaySeconds: {$delayInSeconds}");

            PlanEmailScheduleJob::dispatch($schedule->id)
                ->delay(now()->addSeconds($delayInSeconds));

            return redirect()->route('message.index')->with('success', 'Email schedule created successfully. Planning in progress...');
        }

    }

    private function calculateOptimalDuration($senderCount, $receiverCount)
    {
        $dailyCapPerSender = 2000;
        $totalDailyCapacity = $senderCount * $dailyCapPerSender;

        if ($receiverCount <= $totalDailyCapacity) {
            return ['value' => 1, 'unit' => 'days'];
        }

        $requiredDays = ceil($receiverCount / $totalDailyCapacity);

        if ($requiredDays <= 7) {
            return ['value' => $requiredDays, 'unit' => 'days'];
        } else {
            return ['value' => ceil($requiredDays / 7), 'unit' => 'weeks'];
        }
    }

    public function show($id)
    {
        $schedule = EmailSchedule::with(['batches' => fn($q) => $q->orderBy('run_at'), 'items', 'message'])->findOrFail($id);
        $counters = [
            'queued' => $schedule->items()->where('state', 'queued')->count(),
            'completed' => $schedule->items()->where('state', 'completed')->count(),
            'failed' => $schedule->items()->where('state', 'failed')->count(),
            'paused' => $schedule->items()->where('state', 'paused')->count(),
            'canceled' => $schedule->items()->where('state', 'canceled')->count(),
        ];

        $queues = QueueControl::orderBy('queue_name')->get();

        return view('dashboard.Messages.show', compact('schedule', 'counters', 'queues'));
    }

    // إدارة الجداول
    // public function pauseSchedule(int $id)
    // {
    //     EmailSchedule::where('id', $id)->update(['status' => 'paused']);
    //     return back()->with('success', 'Schedule paused successfully');
    // }

    // public function resumeSchedule(int $id)
    // {
    //     EmailSchedule::where('id', $id)->update(['status' => 'running']);
    //     return back()->with('success', 'Schedule resumed successfully');
    // }

    // public function cancelSchedule(int $id)
    // {
    //     EmailSchedule::where('id', $id)->update(['status' => 'canceled']);
    //     ScheduleItem::where('email_schedule_id', $id)
    //         ->whereIn('state', ['queued', 'paused'])
    //         ->update(['state' => 'canceled']);
    //     return back()->with('success', 'Schedule canceled successfully');
    // }

    // إدارة الطوابير
    public function queuePause(int $queue)
    {
        QueueControl::where('email_schedule_id', $queue)->update(['state' => 'paused']);
        EmailSchedule::where('id', $queue)->update(['status' => 'paused']);
        return back()->with('success', 'Queue paused successfully');
    }

    public function queueResume(string $queue)
    {
        QueueControl::where('email_schedule_id', $queue)->update(['state' => 'running']);
        EmailSchedule::where('id', $queue)->update(['status' => 'running']);
        return back()->with('success', 'Queue resumed successfully');
    }
    public function cancel(string $queue)
    {
        QueueControl::where('email_schedule_id', $queue)->delete();
        EmailSchedule::where('id', $queue)->delete();
        ScheduleItem::where('email_schedule_id', $queue)->delete();
        return back()->with('success', 'Queue Deleted successfully');
    }

    // AJAX Methods
    public function getSubcategoriesReceiversAndSenders(Request $request)
    {
        $categoryIds = $request->query('category_ids', []);
        $senderIds = $request->query('sender_ids', []);

        $subcategories = [];
        $receivers = [];
        $senders = [];

        if (!empty($categoryIds)) {
            $subcategories = SubCategory::whereIn('category_id', $categoryIds)
                ->select('id', 'name', 'category_id')
                ->get();

            $receivers = DataExcel::whereIn('category_id', $categoryIds)
                ->whereNotNull('email')->where('email', '<>', '')
                ->select('id', 'email')
                ->get();
        }

        if (!empty($senderIds)) {
            $senders = Sender::whereIn('id', $senderIds)
                ->select('id', 'name', 'email')
                ->get();
        }

        return response()->json([
            'subcategories' => $subcategories,
            'receivers' => $receivers,
            'senders' => $senders
        ]);
    }

    public function getTemplateData(Request $request)
    {
        $templateId = $request->input('template_id');
        $template = Tempelete::find($templateId);

        if (!$template) {
            return response()->json(['success' => false]);
        }

        return response()->json([
            'success' => true,
            'template' => [
                'subject' => $template->subject,
                'content' => $template->content
            ]
        ]);
    }

    public function testing(Request $request)
    {
        $page = max(1, (int) $request->query('page', 1));
        $perPage = max(10, min(1000, (int) $request->query('per_page', 500)));
        $categoryIds = $request->query('category_ids', []);

        if (empty($categoryIds)) {
            return response()->json([
                'results' => [],
                'pagination' => ['more' => false],
                'total' => 0
            ]);
        }
        // $query = DataExcel::query()
        //     ->whereNotNull('email')
        //     ->where('email', '<>', '')
        //     ->whereIn('category_id', (array) $categoryIds)->whereNotIn('status', ['complete', 'running']);
$query = DataExcel::query()
    ->whereNotNull('email')
    ->where('email', '<>', '')
    ->whereIn('category_id', (array) $categoryIds)
    ->where('status', 'pending'); // ✅ هنا الشرط الجديد


        $paginator = $query->select('id', 'email')
            ->orderBy('email')
            ->paginate($perPage, ['*'], 'page', $page);

        $mapped = $paginator->items();
        $results = array_map(function ($row) {
            return ['id' => $row->id, 'email' => $row->email];
        }, $mapped);

        return response()->json([
            'results' => $results,
            'pagination' => ['more' => $paginator->hasMorePages()],
            'total' => $paginator->total()
        ]);
    }

    public function calculateDuration(Request $request)
    {
        $request->validate([
            'sender_count' => 'required|integer|min:1',
            'receiver_count' => 'required|integer|min:1'
        ]);

        $duration = $this->calculateOptimalDuration($request->sender_count, $request->receiver_count);

        return response()->json([
            'success' => true,
            'duration' => $duration,
            'message' => "Optimal duration: {$duration['value']} {$duration['unit']}"
        ]);
    }

    public function destroy(Request $request, $id)
    {
        $message = Message::with(['sender', 'reciever'])->findOrFail($id);
        $message->delete();

        return redirect()->route('message.index')->with('success', 'Message deleted successfully');
    }
}
